package com.file.client;

import com.file.client.sdk.HttpUtil;
import com.file.client.sdk.Method;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

/**
 * @author： zl
 * @date 2022年2月18日 10:08
 * @description：文件服务器客户端
 * @modifiedBy：zl
 * @version: 1.0
 */
public class HttpClient {

    private static final Logger logger = LoggerFactory.getLogger(HttpClient.class);

    /**
     * 根据指定URL将文件上传到服务器
     *
     * @param urlPath  地址
     * @param fileURL 文件url参数
     * @return 返回uuid
     */
    public static String doPost(String urlPath,String fileURL) {
        File file = new File(fileURL.trim());
        String fileName = file.getName();
        String fileDir = fileURL.substring(0,fileURL.lastIndexOf("/")+1);
        //use test
        logger.info("fileName: "+fileName+" dir: "+fileDir);
        return doPost(urlPath,fileDir,fileName);
    }

    /**
     * 根据指定URL将文件上传到服务器
     *
     * @param urlPath  地址
     * @param uploadDir 文件地址
     * @param fileName 文件名
     * @return 返回uuid
     */
    public static String doPost(String urlPath,String uploadDir,String fileName) {
        String result = "";
        File file;
        try {
            // 定义数据分隔线
            String BOUNDARY = "========7d4a6d158c9";
            // 服务器的域名
            URL realurl = new URL(urlPath);
            // 发送POST请求必须设置如下两行
            HttpURLConnection connection = (HttpURLConnection) realurl.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setUseCaches(false);
            connection.setRequestMethod(String.valueOf(Method.POST));
            connection.setRequestProperty("Connection","Keep-Alive");
            connection.setRequestProperty("Charset","UTF-8");
            connection.setRequestProperty("Content-Type","multipart/form-data; boundary=" + BOUNDARY);

            // 头
            // 传输内容
            StringBuffer contentBody = new StringBuffer("--" + BOUNDARY);
            // 尾
            //输出
            OutputStream os = connection.getOutputStream();
            // 1. 处理普通表单域(即形如key = value对)的POST请求（这里也可以循环处理多个字段，或直接给json）
            //这里看过其他的资料，都没有尝试成功是因为下面多给了个Content-Type
            //form-data  这个是form上传 可以模拟任何类型
            //boundaryPrefix = "--";
            contentBody.append("\r\n")
                    .append("Content-Disposition: form-data; name=\"")
                    .append("param" + "\"")
                    .append("\r\n")
                    .append("\r\n")
//                    .append(param)
                    .append("\r\n")
                    .append("--")
                    .append(BOUNDARY);
            String boundaryMessage1 =contentBody.toString();

            os.write(boundaryMessage1.getBytes("utf-8"));

            // 2. 处理file文件的POST请求（多个file可以循环处理）
            contentBody = new StringBuffer();
            // form中field的名称
            contentBody.append("\r\n")
                    .append("Content-Disposition:form-data; name=\"")
                    .append("file" + "\"; ")   // form中field的名称
                    .append("filename=\"").append(fileName).append("\"")   //上传文件的文件名，包括目录
                    .append("\r\n")
                    .append("Content-Type:multipart/form-data")
                    .append("\r\n\r\n");
            String boundaryMessage2 = contentBody.toString();
            System.out.println(boundaryMessage2);

            os.write(boundaryMessage2.getBytes("utf-8"));

            // 开始真正向服务器写文件
            String path = uploadDir + File.separatorChar + fileName;
            file = new File(path);
            DataInputStream dis= new DataInputStream(new FileInputStream(file));
            int bytes = 0;
            byte[] bufferOut =new byte[(int) file.length()];
            bytes =dis.read(bufferOut);
            os.write(bufferOut,0, bytes);
            dis.close();
            byte[] endData = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();
            os.write(endData);
            os.flush();
            os.close();

            // 4. 从服务器获得回答的内容
            String strLine="";
            String strResponse ="";
            InputStream in =connection.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            while((strLine =reader.readLine()) != null)
            {
                strResponse +=strLine +"\n";
            }
           logger.info(strResponse);
            return strResponse;
        } catch (Exception e) {
            logger.debug("发送POST请求出现异常！" + e);
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 根据指定URL将文件下载到指定目标位置
     *
     * @param urlPath 下载路径
     * @param downloadUrl 文件存放url
     * @return 返回下载文件
     */
    public static File downloadFile(String urlPath, String downloadUrl) {
        File file = new File(downloadUrl.trim());
        String fileName = file.getName();
        String downloadDir = downloadUrl.substring(0,downloadUrl.lastIndexOf("/"));
        return get(urlPath,downloadDir,fileName);
    }

    /**
     * 根据指定URL将文件下载到指定目标位置
     *
     * @param urlPath 下载路径
     * @param downloadDir 文件存放目录
     * @param fileName 文件名
     * @return 返回下载文件
     */
    public static File get(String urlPath, String downloadDir,String fileName) {
        File file = null;
        String msg = "文件下载失败！";
        try {
            // 统一资源
            URL url = new URL(urlPath);
            // 连接类的父类，抽象类
            URLConnection urlConnection = url.openConnection();
            // http的连接类
            HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
            //设置超时
            httpURLConnection.setConnectTimeout(1000*5);
            //设置请求方式，默认是GET
            httpURLConnection.setRequestMethod("GET");
            // 设置字符编码
            httpURLConnection.setRequestProperty("Charset", "UTF-8");
            // 打开到此 URL引用的资源的通信链接（如果尚未建立这样的连接）。
            httpURLConnection.connect();

            // 建立链接从请求中获取数据
            URLConnection con = url.openConnection();
            BufferedInputStream bin = new BufferedInputStream(httpURLConnection.getInputStream());

            // 指定存放位置
            String path = downloadDir + File.separatorChar + fileName;
            file = new File(path);
            // 校验文件夹目录是否存在，不存在就创建一个目录
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }

            OutputStream os = new FileOutputStream(file);
            int size = 0;
            int len = 0;
            byte[] buf = new byte[2048];
            while ((size = bin.read(buf)) != -1) {
                len += size;
                os.write(buf, 0, size);
            }

            // 关闭资源
            bin.close();
            os.close();

            msg = "文件下载成功！";
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            logger.debug(msg);
            e.printStackTrace();
        } finally {
            logger.info(msg);
            return file;
        }

    }


    /**
     * 向指定的URL发送GET方法的请求
     * @param url    发送请求的URL
     * @return       远程资源的响应结果
     */
    public static String sendGet(String url) {
        return HttpUtil.sendGet(url);
    }
}
